package org.dtrd.modules.patient.controller;

import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.dtrd.base.BaseController;
import org.dtrd.common.api.vo.Result;
import org.dtrd.common.util.PasswordUtil;
import org.dtrd.common.util.RedisUtil;
import org.dtrd.common.util.oConvertUtils;
import org.dtrd.modules.base.service.BaseCommonService;
import org.dtrd.modules.patient.entity.bean.PatientPublicAccountInfo;
import org.dtrd.modules.patient.entity.po.DtrdEntRdPatient;
import org.dtrd.modules.patient.service.IDtrdEntRdPatientService;
import org.dtrd.modules.system.entity.SysUser;
import org.dtrd.modules.system.service.ISysUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;

import static org.dtrd.common.constant.CommonConstant.OPERATE_TYPE_QUERY;
import static org.dtrd.config.system.SystemState.ResponseState.*;

/**
 * @author qr
 * @date 2022/1/12 14:08
 */
@Api(tags = "患者公众号相关接口")
@RestController
@RequestMapping("/patient/pa/")
@Slf4j
public class PatientPublicAccountController extends BaseController {

    @Autowired
    private IDtrdEntRdPatientService patientService;
    @Autowired
    private BaseCommonService baseCommonService;
    @Autowired
    private ISysUserService userService;
    @Resource
    @Lazy
    private RedisUtil redisUtil;

    @ApiOperation("获取患者信息-公众号")
    @GetMapping("/get")
    public Result<?> get(@ApiParam("患者id") @RequestParam Integer patientId){
        PatientPublicAccountInfo info = patientService.getPatientPublicAccountInfo(patientId);
        String logContent = String.format("获取患者信息-公众好，查询患者id：%d", patientId);
        baseCommonService.addLog(logContent, OPERATE_TYPE_QUERY);
        return info == null ? error(STATE_NO_RECORD) : Result.OK(info);
    }

    @ApiOperation("更新或修改患者公众号信息")
    @PostMapping("/edit")
    public Result<?> saveOrUpdatePatientPublicAccountInfo(
            @RequestBody PatientPublicAccountInfo patientPublicAccountInfo
    ){
        if (patientPublicAccountInfo.getPatientId() == null) {
            return error(STATE_PARAMS_MISSING);
        }
        boolean result = patientService.saveOrUpdatePatientInfo(patientPublicAccountInfo);
        String logContent = String.format("更新或修改患者公众号信息，更新患者id: %d, 更新内容id：%s", patientPublicAccountInfo.getPatientId(), patientPublicAccountInfo);
        baseCommonService.addLog(logContent, OPERATE_TYPE_QUERY);
        return result ? Result.OK() : error(STATE_OPERATION_FAILURE);
    }

    @ApiOperation("同步患者手机号")
    @PostMapping("/synchMobile")
    public Result<?> saveOrUpdate(@RequestBody JSONObject json){
        String smscode = json.getString("smsmode");
        String phone = json.getString("phone");
        Integer patientId = json.getInteger("patientId");
        // 空参校验
        if (patientId == null || StrUtil.isBlank(phone) || StrUtil.isBlank(smscode)) {
            return Result.error("缺少必要参数");
        }
        Object object = redisUtil.get(phone);
        if (null == object) {
            return Result.error("短信验证码失效！");
        }
        if (!smscode.equals(object)) {
            return Result.error("短信验证码不匹配！");
        }
        patientId = patientService.bindMobileToPatient(patientId, phone);
        return Result.OK(patientId);
    }

    @ApiOperation("更新患者手机号")
    @PostMapping("/updateMobile")
    public Result<?> updatePatientMobile(@RequestBody JSONObject json) {
        String smscode = json.getString("smsmode");
        String phone = json.getString("phone");
        Integer patientId = json.getInteger("patientId");
        log.info("患者: {}, 修改手机号: {}, 验证码: {}", patientId, phone, smscode);
        Result<SysUser> result = new Result<>();
        if (patientId == null || StrUtil.isBlank(phone) || StrUtil.isBlank(smscode)) {
            result.setMessage("缺少必要参数");
            result.setSuccess(false);
            return result;
        }
        if (!patientService.checkPatientMobile(phone, patientId)) {
            result.setMessage("待修改的手机号已存在");
            result.setSuccess(false);
            return result;
        }
        Object object = redisUtil.get(phone);
        if (null == object) {
            result.setMessage("短信验证码失效！");
            result.setSuccess(false);
            return result;
        }
        if (!smscode.equals(object)) {
            result.setMessage("短信验证码不匹配！");
            result.setSuccess(false);
            return result;
        }
        DtrdEntRdPatient patient = patientService.getById(patientId);
        String oldMobile = patient.getPatientsMobile();
        SysUser user = userService.getUserByPhone(oldMobile);
        if (user == null) {
            return Result.error("用户不存在！");
        }
        // 更新 patient 表
        patient.setPatientsMobile(phone);
        patientService.updateById(patient);
        // 更新 sysUser 表
        user.setPhone(phone);
        userService.updateById(user);
        return Result.OK("手机号设置成功!");
    }

    @ApiOperation("更新患者密码")
    @PostMapping("/updatePwd")
    public Result<?> updatePatientPassword(@RequestBody JSONObject json) {
        String oldPwd = json.getString("oldPwd");
        String newPwd = json.getString("newPwd");
        Integer patientId = json.getInteger("patientId");
        Result<SysUser> result = new Result<>();
        if (oConvertUtils.isEmpty(patientId) || oConvertUtils.isEmpty(newPwd) || oConvertUtils.isEmpty(oldPwd)) {
            result.setMessage("修改密码失败！");
            result.setSuccess(false);
            return result;
        }
        // 查找两张表的对象
        DtrdEntRdPatient patient = patientService.getById(patientId);
        if (patient == null) {
            return Result.error("用户不存在!");
        }
        String oldMobile = patient.getPatientsMobile();
        SysUser user = userService.getUserByPhone(oldMobile);
        if (user == null) {
            return Result.error("用户不存在！");
        }
        // 校验旧的密码是否和新密码相同
        String encryptOldPwd = PasswordUtil.encrypt(user.getUsername(), oldPwd, user.getSalt());
        if (!encryptOldPwd.equals(user.getPassword())) {
            result.setMessage("原始密码错误！");
            result.setSuccess(false);
            return result;
        }
        // 更新密码
        String realNewPwd = PasswordUtil.encrypt(user.getUsername(), newPwd, user.getSalt());
        // 更新 patient 表
        patient.setPatientsPassword(realNewPwd);
        patientService.updateById(patient);
        // 更新 sysUser 表
        user.setPassword(realNewPwd);
        userService.updateById(user);
        return Result.OK("修改密码成功!");
    }
}
